#include<func.h>
#include"head.h"
//多线程相关函数
int makeWorker(threadPool_t *pThreadPool){
    for(int i=0;i<pThreadPool->threadNum;i++){
        pthread_create(pThreadPool->tidArr+i,NULL,threadFunc,(void *)pThreadPool);
    }
}
void unlock(void *parg){
    pthread_mutex_t *pMutex = (pthread_mutex_t *)parg;
    pthread_mutex_unlock(pMutex);
}

// cd 进入对应目录
int cd_c(char *pathBuf, int netFd){
    //char relativePath[] = "cd review/test";
    char filePath[1024] = {0};
    char *path = strtok(pathBuf, " ");
    path=strtok(NULL,"\n");
    sprintf(filePath, "%s%s", path, "$");
    printf("%s\n",filePath);
    send(netFd, filePath, strlen(filePath), MSG_NOSIGNAL);
    savelog(__FUNCTION__);
}
//pwd 显示目前所在路径
int pwd(int netFd){

    char buf[1024]={0};//主动分配
    memset(buf,0,sizeof(buf));
    char *ret = getcwd(buf, sizeof(buf));
      
    send(netFd, buf,sizeof(buf),0);
    savelog(__FUNCTION__);
    return 0;
}
//puts 将本地文件上传至客户端
int sendFile(char filename[],int sdf)
{
   train_t t;
   int fd=open(filename,O_RDWR);
   bzero(&t,sizeof(t));
   struct stat st;
   int retstat=fstat(fd,&st);
   ERROR_CHECK(retstat,-1,"fstat");
   long localsize=st.st_size; //服务端被下载文件大小
   printf("服务端被下载文件大小%ldM\n",localsize/M);
   t.dataLength=sizeof(st.st_size);
   memcpy(t.buf,&st.st_size,sizeof(st.st_size));
   int ret6=send(sdf,&t,t.dataLength+sizeof(t.dataLength),MSG_NOSIGNAL);//发送客户端文件的大小长度+文件大小
   ERROR_CHECK(ret6,-1,"发送服务端被下载文件的大小长度与大小");
   long filesize;
   int dataLength;
   int ret1=recv(sdf,&dataLength,sizeof(int),MSG_WAITALL); //接收客户端同名文件大小长度
   int ret2=recv(sdf,&filesize,dataLength,MSG_WAITALL); //接收客户端同名文件大小
   ERROR_CHECK(ret1,-1,"接收服客户端同名文件大小长度");
   char* p=(char*)mmap(NULL,st.st_size,PROT_READ,MAP_SHARED,fd,0);
   if(p!=NULL)
   {
     printf("mmap成功\n");
   }
   off_t index=0;
   if(filesize!=0)
   {
      printf("断点重传\n");
      printf("客户端同名文件大小%ldM\n",filesize/M);
      index=filesize;
   }
   int i=0;
   while(index<localsize)
   {
     if(localsize-index >= sizeof(t.buf))
     {
       t.dataLength=sizeof(t.buf);
     }
     else
     {
       t.dataLength=localsize-index;
     }
       memcpy(t.buf,p+index,t.dataLength);
       index=index+t.dataLength;
       int ret7=send(sdf,&t,sizeof(int)+t.dataLength,MSG_NOSIGNAL);
       //printf("%5.2lf%% %ld\r",100.0*index/localsize,index);
       //fflush(stdout);
    }
    t.dataLength=0;
    send(sdf,&t,sizeof(int),MSG_NOSIGNAL);
    int ret8=munmap(p,st.st_size);
    ERROR_CHECK(ret8,-1,"解除mmap映射");
    printf("发送文件大小: %ldM\n",index/M);
    close(fd);
    savelog(__FUNCTION__);
    return 0;
   }
//gets 文件名 接收客户端文件到本地
int recvFile(int netFd ,char *fileName){
    train_t t;
    //打开或者创建临时文件
    int fd = open(fileName,O_RDWR|O_CREAT,0666);
    ERROR_CHECK(fd,-1,"open");
    bzero(&t,sizeof(t));
    long fileSize;
    //获取描述文件总大小的火车头
    int ret = recv(netFd,&t.dataLength,sizeof(t.dataLength),MSG_WAITALL);
    ERROR_CHECK(ret,-1,"recv dataLength");
    //再获取文件总大小
    recv(netFd,&fileSize,t.dataLength,MSG_WAITALL);
    ERROR_CHECK(ret,-1,"recv fileSize");
    printf("目标文件大小: %ldM\n",fileSize/M);
    //获取临时文件总大小，并发送给发送端
    struct stat statbuf;
    ret = fstat(fd,&statbuf);
    ERROR_CHECK(ret,-1,"fstat");
    bzero(&t,sizeof(t));
    t.dataLength = sizeof(statbuf.st_size);
    //把文件大小放到小火车车厢中
    memcpy(t.buf,&statbuf.st_size,sizeof(statbuf.st_size));
    //再发送文件大小
    send(netFd,&t,sizeof(t.dataLength)+t.dataLength,MSG_NOSIGNAL);
    off_t downSize = statbuf.st_size;//当前已经下载文件的大小
    printf("当前文件大小:%ldM\n",downSize/M);
    off_t needSize = (fileSize - downSize)/M;//需下载的量
    printf("需下载:%ldM\n",needSize);
    off_t lastSize = statbuf.st_size;//在上一次完成下载文件总大小千分之一时的文件大小
    off_t slice = fileSize/1000;//总文件大小千分之一
    //设置当前文件偏移量，让其在之前数据之后读写
    if(statbuf.st_size != 0){
        lseek(fd,downSize,SEEK_SET);
    }
        while(1){
             bzero(&t,sizeof(t));
             ret = recv(netFd,&t.dataLength,sizeof(int),MSG_WAITALL);
             ERROR_CHECK(ret,-1,"recv dataLength");
             if(t.dataLength == 0){
                 break;
             }
             downSize += t.dataLength;
             if(downSize - lastSize > slice){
                 double precent = (double)downSize/fileSize;
                 printf("[%5.2lf%%]\r",100.0*precent);
                 fflush(stdout);
             }
             ret = recv(netFd,t.buf,t.dataLength,MSG_WAITALL);
             ERROR_CHECK(ret,-1,"recv t.buf");
             write(fd,t.buf,t.dataLength);
        }
    printf("[100.00%s]\n","%");
    close(fd);
    savelog(__FUNCTION__);
}
//删除文件
/* int remove_net(int netfd){
    char filename[80];
    char buf[50] = {0};
    recv(netfd,filename,sizeof(filename),0);
    //printf("The file to delete:");
    //scanf("%s", filename);
    if( remove(filename) == 0 ){
        printf("Removed %s\n.", filename);
        strcpy(buf, "文件删除成功");
        send(netfd, buf, strlen(buf), 0);
    }
    else{
        perror("remove");
        strcpy(buf, "删除失败或文件不存在！");
        send(netfd, buf, strlen(buf), 0);
    }
    savelog(__FUNCTION__);
} */
int remove_net(int netfd,char *filename){
    char buf[50] = {0};
    char file_name[80]={0};
    puts(filename);
    strcpy(file_name,filename);
    puts(file_name);
    if( remove(file_name) == 0 ){
        printf("Removed %s\n.", file_name);
    }
    else{
        perror("remove");
    }
}




//日志记录
void savelog(const char *funcnam){//传入函数名字
    char buf[4096]={0};
    FILE* fd=fopen("log","a+");
    if(fd==NULL){
        printf("failed in open file\n");
        exit(1);
    }
    savetime(buf);
    strcat(buf," the operate record produced by function:");
    strcat(buf,funcnam);
    strcat(buf,"\n");
    fputs(buf,fd);
    fclose(fd);
}
void savetime(char *buf){
    char timebuf[32]={0};//记录时间
    time_t timep;
    struct tm *p;
    time(&timep);
    p=localtime(&timep);
    strftime(timebuf,32,"%m/%d/%Y %H:%M:%S",p);
    strcpy(buf,timebuf);
}
//查看日志
void viewlog(int netFd){//查看日志
	FILE *pfile = fopen("log", "r");//打开文件
	if (pfile == NULL) {
		printf("open file failed!\n");
		exit(1);
	}
	//读取文件长度,读完后把文件指针复位到开头
	fseek(pfile,0, SEEK_END);
	int file_length = ftell(pfile);
	rewind(pfile);
	//申请一段内存空间用来放文件中的文本内容，并置零
	int text_length = file_length * sizeof(char) + 1;
	char* text_buffer = (char*)malloc(text_length);
	memset(text_buffer, 0, text_length);
	//把文件文本内容读到申请的内存空间中
	int read_length = fread(text_buffer, 1, file_length, pfile);
	if (read_length != file_length) {
		printf("read file failed!\n");
		exit(1);
	}
	//打印文件文本内容，释放申请的内存空间，关闭文件流
	//printf("%s",text_buffer);
  send(netFd,text_buffer,strlen(text_buffer),0);
	free(text_buffer);
	fclose(pfile);
  savelog(__FUNCTION__);
}

/* //日志记录
void savelog(const char *funcnam){//传入函数名字
    char buf[4096]={0};
    char table[100]={"yongHu"};
    savetime(buf);
    strcat(buf," the operate record produced by function:");
    strcat(buf,funcnam);
    //strcat(buf,"\n");
    //fputs(buf,fd);
    MYSQL *db = mysql_init(NULL);
    char * host = "localhost";
    char * user = "root";
    char * password = "123";
    char * database = "netDisk";
    MYSQL * ret = mysql_real_connect(db,host,user,password,database,0,NULL,0);
    if(ret != 0){
        printf("mysql connect successed\n");
    }
    else{
        printf("error: %s\n",mysql_error(db));
        exit(-1);
    }
    putInSqlRiZhi(buf,db);
    mysql_close(db);
}
void savetime(char *buf){
    char timebuf[32]={0};//记录时间
    time_t timep;
    struct tm *p;
    time(&timep);
    p=localtime(&timep);
    strftime(timebuf,32,"%m/%d/%Y %H:%M:%S",p);
    strcpy(buf,timebuf);
}
//查看日志
void viewlog(int netFd){//查看日志
	char buf[40960]={0};
    char table[100]={"yongHu"};
    MYSQL *db = mysql_init(NULL);
    char * host = "localhost";
    char * user = "root";
    char * password = "123";
    char * database = "netDisk";
    MYSQL * ret = mysql_real_connect(db,host,user,password,database,0,NULL,0);
    if(ret != 0){
        printf("mysql connect successed\n");
    }
    else{
        printf("error: %s\n",mysql_error(db));
        exit(-1);
    }
    outRiZhi(buf,db);
    send(netFd,buf,sizeof(buf),0);
    mysql_close(db);
    savelog(__FUNCTION__);
}
 */